﻿using AiBLSmartEdu.Module.SmartMaths.API.DTOs;
using AutoMapper;
using Domain;
using Domain.Entities;
using FrameworkCore.DI;
using FrameworkCore.Extensions;
using FrameworkCore.Helpers;
using FrameworkCore.Models;
using FrameworkCore.Repositories;
using Microsoft.EntityFrameworkCore;

namespace AiBLSmartEdu.Module.SmartMaths.API.Services;

#nullable disable

/// <summary>
/// 数学助手服务
/// 提供数学相关问题的处理功能。
/// </summary>
public class MathQuestionServices : IScopedDependency
{
    private readonly IRepository<MathQuestion> __mathQuestionRepository;
    private readonly IMapper _mapper;
    private readonly MathsHelpers _mathsHelpers;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="mathQuestionRepository">仓储</param>
    /// <param name="mapper">对象映射</param>
    /// <param name="mathsHelpers">数学助手</param>
    public MathQuestionServices(IRepository<MathQuestion> mathQuestionRepository, IMapper mapper, MathsHelpers mathsHelpers)
    {
        __mathQuestionRepository = mathQuestionRepository;
        _mapper = mapper;
        _mathsHelpers = mathsHelpers;
    }

    /// <summary>
    /// 分页查询
    /// </summary>
    /// <param name="filter">分页输入模型</param>
    /// <returns></returns>
    public async Task<PageResult<QuestionOutputModel>> PageAsync(QuestionPaginationFilter filter)
    {
        return (await __mathQuestionRepository.GetOrderedQueryable(query =>
        {
            return query.WhereIf(!filter.Question.IsNullOrWhiteSpace(), x => x.Question.Contains(filter.Question))
                        .WhereIf(filter.Status.HasValue, x => x.Status == filter.Status)
                        .WhereIf(filter.IsFavorited.HasValue, x => x.IsFavorited == filter.IsFavorited);

        }, filter).ProjectToPaginatedDataAsync<MathQuestion, QuestionOutputModel>(
            filter.PageNumber,
            filter.PageSize,
            _mapper.ConfigurationProvider
        )).ToPageList();
    }

    /// <summary>
    /// 创建新的数学问题及答案
    /// </summary>
    /// <param name="input">包含新问题信息的输入模型</param>
    /// <returns>一个表示异步操作的任务</returns>
    public async Task CreateAsync(QuestionCreateInputModel input)
    {
        var isExist = __mathQuestionRepository.Query(x => x.Question == input.Question).Any();
        ExceptionHelper.ThrowIfTrue(isExist, "问题已存在");

        var model = _mapper.Map<MathQuestion>(input);
        model.Answer = await _mathsHelpers.FetchAnswerAsync(input.Question);
        await __mathQuestionRepository.InsertAsync(model);
    }

    /// <summary>
    /// 修改状态
    /// </summary>
    /// <param name="id"></param>
    /// <param name="status"></param>
    /// <returns></returns>
    public async Task UpdateStatusAsync(long id, MathQuestionStatus status)
    {
        await __mathQuestionRepository.UpdateAsync(x => x
            .SetProperty(p => p.Status, p => status), w => w.Id == id);
    }

    /// <summary>
    /// 是否收藏
    /// </summary>
    /// <param name="id">唯一标识</param>
    /// <returns></returns>
    public async Task IsFavoritedAsync(long id)
    {
        await __mathQuestionRepository.UpdateAsync(x => x.SetProperty(p => p.IsFavorited, p => !p.IsFavorited), w => w.Id == id);
    }

    /// <summary>
    /// 查询答案
    /// </summary>
    /// <param name="id">唯一表示</param>
    /// <returns></returns>
    public async Task<string> QueryAnswerAsync(long id) 
    {
        var question = await __mathQuestionRepository.Query(x => x.Id == id).FirstOrDefaultAsync();
        ExceptionHelper.ThrowIfNull(question, "问题不存在");
        ExceptionHelper.ThrowIfNull(question.Answer, "答案不存在");

        return await _mathsHelpers.ConvertXmlToHtmlAsync(question.Answer, question.Question);
    }

    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="ids">唯一标识，多个使用英文状态下的逗号（,）隔开</param>
    /// <returns></returns>
    public async Task DeleteAsync(string ids)
    {
        ExceptionHelper.ThrowIfNull(ids, "删除的唯一标识不能为空");

        List<long> idsToDelste = ids
            .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)  // 分割字符串
            .Select(id =>
            {
                if (long.TryParse(id.Trim(), out long result))
                {
                    return result;
                }
                else
                {
                    ExceptionHelper.ThrowIfTrue(true, "无效的标识");
                    return 0;
                }
            }).ToList();

        await __mathQuestionRepository.DeleteAsync(x => idsToDelste.Contains(x.Id));
    }
}
